package com.xm.container;

import com.xm.annotation.XmAutowired;
import com.xm.annotation.XmController;
import com.xm.annotation.XmService;
import com.xm.utils.ObjectUtil;
import com.xm.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 黄家伟
 * @version v1.0.0
 * @mail huangwei_xm@163.com
 * @copyright <a href="http://www.huangwei.work">oneself</a>
 * @description BeanFactoryAware描述如下
 * <pre>
 *    容器管理接口
 * </pre>
 * @since 2021/4/24 20:46
 */
public interface BeanFactoryAware {
    Logger log = LoggerFactory.getLogger(BeanFactoryAware.class);

    /**
     * beans
     */
    Map<String, Object> beans = new HashMap<>();

    /**
     * 根据class获取bean
     */
    default <B> B getBean(Class<?> clazz) {
        return (B) beans.get(clazz.getSimpleName());
    }

    /**
     * 获取名称bean
     */
    default Object getBean(String name) {
        return beans.get(name);
    }

    /**
     * 创建bean，默认按照className创建
     */
    default void createBean(String fullyClassName) {
        try {
            createBean(Class.forName(fullyClassName).getSimpleName(), fullyClassName);
        } catch (ClassNotFoundException e) {
            log.error("没有发现类，创建bean[className={}]异常：{}", fullyClassName, e.getMessage());
            e.printStackTrace();
        }
    }

    default void createBean(String id, String fullyClassName) {
        try {
            createBean(id, Class.forName(fullyClassName));
        } catch (ClassNotFoundException e) {
            log.error("没有发现类，创建bean[{}]异常：{}", id, e.getMessage());
            e.printStackTrace();
        }
    }

    default void createBean(String id, Class<?> clazz) {
        try {
            beans.put(id, clazz.newInstance());
        } catch (InstantiationException e) {
            log.error("实例化失败，创建bean[{}]异常：{}", id, e.getMessage());
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            log.error("权限不足，创建bean[{}]异常：{}", id, e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 刷新bean
     *
     * @param id
     * @param obj
     */
    default void flushBean(String id, Object obj) {
        beans.put(id, obj);
    }

    /**
     * 刷新bean
     *
     * @param obj
     */
    default void flushBean(Object obj) {
        beans.put(obj.getClass().getSimpleName(), obj);
    }

    /**
     * 初始化bean
     */
    default void initBean(Class<?> aClass) {
        if (ObjectUtil.isNotAnnotationAndInterface(aClass)) {
            FlagPar<String, Boolean> flagPar = getBeanName(aClass);
            if (flagPar.getRight()) {
                createBean(flagPar.getLeft(),aClass);
            }
        }
    }

    /**
     * 自动装配
     */
    default void initAutowired(Class<?> aClass) {
        if (ObjectUtil.isNotAnnotationAndInterface(aClass)) {
            FlagPar<String, Boolean> flagParBean = getBeanName(aClass);
            if (flagParBean.getRight()) {
                // 该类已经交由容器管理
                Field[] fields = aClass.getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    FlagPar<String,Boolean> flagParAutowired = getAutowiredName(field);
                    if (flagParAutowired.getRight()) {
                        // 可以注入
                        Object value = getBean(flagParAutowired.getLeft());
                        Object target = getBean(flagParBean.getLeft());
                        try {
                            field.setAccessible(true);
                            field.set(target,value);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }

                }
            }

        }

    }

   default FlagPar<String, Boolean> getAutowiredName(Field field) {
       Annotation[] annotations = field.getAnnotations();
       String simpleName = field.getType().getSimpleName();
       FlagPar<String, Boolean> flagPar = new FlagPar<>(simpleName, false);
       for (int j = 0; j < annotations.length; j++) {
           Annotation annotation = annotations[j];
           String value = "";
           if (annotation instanceof XmAutowired) {
               value = ((XmAutowired) annotation).value();
           } else {
               continue;
           }
           if (StringUtil.isNotEmpty(value)) {
               simpleName = value;
           }
           if (ObjectUtil.isNotEmpty(getBean(simpleName))) {
               // 容器中存在，再考虑注入
                flagPar.setLeft(simpleName);
                flagPar.setRight(true);
           }
           break;
       }
       return flagPar;
   }

    default FlagPar<String, Boolean> getBeanName(Class<?> aClass) {
        String simpleName = aClass.getSimpleName();
        FlagPar<String, Boolean> flagPar = new FlagPar<String, Boolean>(simpleName,true);
        if (!beans.containsKey(simpleName)) {
            // 容器中不存在
            Annotation[] annotations = aClass.getAnnotations();
            boolean flag = false;
            for (int i = 0; i < annotations.length; i++) {
                Annotation annotation = annotations[i];
                String value = "";
                if (annotation instanceof XmController) {
                    value = ((XmController) annotation).value();
                } else if (annotation instanceof XmService) {
                    value = ((XmService) annotation).value();
                } else {
                    continue;
                }
                if (StringUtil.isNotEmpty(value)) {
                    simpleName = value;
                }
                // 可以交由容器管理
                flag = true;
                break;
            }
            flagPar.setRight(flag);
            flagPar.setLeft(simpleName);
        }
        return flagPar;
    }

}
